﻿using System;
using Brouteforce.utilities;
using Microsoft.Xna.Framework;

namespace Brouteforce.OldStuff.oldapi {
    public class Position{

        public Rectangle OnScreenPosition;
        public Vector2 RealPosition;
        
        public Vector2 Velocity;

        public Position(float x, float y, int height, int width){
            OnScreenPosition = new Rectangle((int)x, (int)y, width, height);
            RealPosition = new Vector2(x, y);
        }

        public float Y{
            get { return RealPosition.Y; }
            set { 
                RealPosition.Y = value;
                OnScreenPosition.Y = (int) value;
            }
        }

        public float X {
            get { return RealPosition.X; }
            set {
                RealPosition.X = value;
                OnScreenPosition.X = (int)value;
            }
        }

        public int Height{
            get { return OnScreenPosition.Height; }
            set { OnScreenPosition.Height = value; }
        }

        /// <summary>
        /// return same position but with randomization of X
        /// </summary>
        /// <returns></returns>
        public Position RandomizeX(Rectangle bounds){
            var ret = new Position(Randoms.Between(bounds.X, bounds.Width - OnScreenPosition.Width), RealPosition.Y, OnScreenPosition.Height, OnScreenPosition.Width);
            ret.Velocity = this.Velocity;
            return ret;
        }

        /// <summary>
        /// return same position but with randomization of X
        /// </summary>
        /// <returns></returns>
        public Position RandomizeXAndWidth(Rectangle xBounds, int minW, int maxW) {
            var ret = new Position(Randoms.Between(xBounds.X, xBounds.Width - OnScreenPosition.Width), RealPosition.Y, OnScreenPosition.Height, Randoms.Between(minW, maxW));
            ret.Velocity = this.Velocity;
            return ret;
        }

        public Position(Rectangle onScreenPosition, Vector2 realPosition){
            OnScreenPosition = onScreenPosition;
            RealPosition = realPosition;
        }

        public Position LinearMove(double timeDelta){
            var newRealPosition = new Vector2(RealPosition.X + ((float)timeDelta) * Velocity.X, RealPosition.Y + ((float)timeDelta) * Velocity.Y);
            var p = new Position(new Rectangle((int) newRealPosition.X, (int) newRealPosition.Y, OnScreenPosition.Width, OnScreenPosition.Height),  newRealPosition);
            p.Velocity = Velocity;
            return p;
        }

        public bool IsIn(Rectangle bounds){
            return bounds.Contains(this.OnScreenPosition);
        }

        /// <summary>
        /// return true if an object is directly on top of another
        /// ex: 
        /// 
        /// this: |
        /// what: ___
        /// 
        /// -------------------------------------------------------
        ///    |   : false if dist = 0, true if dist = 1
        /// _______
        /// -------------------------------------------------------
        /// 
        /// ___|__ : true if dist = 0 and true if dist = 1
        /// -------------------------------------------------------
        /// 
        ///    |   : false if dist = 0, false if dist = 1
        ///
        ///  _______
        /// -------------------------------------------------------
        /// 
        /// __________
        /// 
        ///     |       :false no matter the distance
        /// -------------------------------------------------------
        /// 
        /// </summary>
        /// <param name="what"></param>
        /// <param name="dist"> </param>
        /// <returns></returns>
        public bool IsDirectlyOnTopOf(Rectangle what, int dist){
            if (IsAboveMe(what)) return false;
            
            var ret = IsWithinXBounds(what)  && Math.Abs(OnScreenPosition.Y + OnScreenPosition.Height - what.Y) <= dist;

            //if (ret){
                //System.Diagnostics.Debugger.Break();
            //}

            return ret;
        }

        /// <summary>
        /// return true if an object is directly below of another
        /// ex: 
        /// 
        /// this: +++
        /// what: ***
        /// 
        /// -------------------------------------------------------
        ///    ***   : false if dist = 0, true if dist = 1
        /// ++++++++
        /// -------------------------------------------------------
        /// 
        /// ++++*+++ : true if dist = 0 and true if dist = 1
        /// -------------------------------------------------------
        /// 
        ///    ***   : false if dist = 0, false if dist = 1
        ///
        ///  +++++++
        /// -------------------------------------------------------
        /// 
        /// +++++++++
        /// 
        ///   ***    :false no matter the distance
        /// -------------------------------------------------------
        /// 
        /// </summary>
        /// <param name="what"></param>
        /// <param name="dist"> </param>
        /// <returns></returns>
        public bool IsDirectlyBelowOf(Rectangle what, int dist) {
            if (IsBelowMe(what)) return false;

            var ret = IsWithinXBounds(what) && Math.Abs(what.Y + what.Height - OnScreenPosition.Y) <= dist;

            //if (ret){
            //    System.Diagnostics.Debugger.Break();
            //}

            return ret;
        }

        /// <summary>
        /// return true if the given rectangle is below me
        /// ex: 
        /// 
        /// this: +++ 
        /// what: ***
        /// ------------------------------------------------
        /// 
        /// ****
        ///    ++++  : false
        /// ------------------------------------------------
        /// ++++
        ///       **** : true
        /// ------------------------------------------------
        /// 
        /// </summary>
        /// <param name="what"></param>
        /// <returns></returns>
        public bool IsBelowMe(Rectangle what){
            return OnScreenPosition.Y + OnScreenPosition.Height < what.Y;
        }

        /// <summary>
        /// return true if the given rectangle is above me
        /// ex: 
        /// 
        /// this: +++ 
        /// what: ***
        /// ------------------------------------------------
        /// 
        /// ****
        ///    ++++  : true
        /// ------------------------------------------------
        /// ++++
        ///       **** : false
        /// ------------------------------------------------
        /// 
        /// </summary>
        /// <param name="what"></param>
        /// <returns></returns>
        public bool IsAboveMe(Rectangle what) {
            return OnScreenPosition.Y > what.Y + what.Height;
        }

        /// <summary>
        /// return true if pos is within the x bounds of this
        /// 
        /// ex:
        /// this: +++
        /// pos: ***
        /// 
        /// ------------------------------------------------
        ///            +++++
        ///    ******           : will return false
        /// ------------------------------------------------
        ///    +++++++
        ///     ***             : will return true
        /// ------------------------------------------------
        ///    +++++++
        ///         ******      : will return true
        /// ------------------------------------------------
        /// 
        /// </summary>
        /// <param name="pos"></param>
        /// <returns></returns>
        public bool IsWithinXBounds(Rectangle pos){
            return pos.X >= OnScreenPosition.X && pos.X <= OnScreenPosition.X + OnScreenPosition.Width;
        }

        public bool IsAbove(Rectangle bounds){
            return bounds.Y > OnScreenPosition.Y;
        }

        public bool IsColidingWith(Position other){
            return this.OnScreenPosition.Intersects(other.OnScreenPosition);
        }
    }
}
